package com.zhijian.medical.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhijian.medical.dao.local.FishHybridMapper;
import com.zhijian.medical.entity.po.ExperimentFish;
import com.zhijian.medical.entity.po.ExperimentFishHybrid;
import com.zhijian.medical.entity.po.ExperimentFishHybridOplog;
import com.zhijian.medical.entity.po.ExperimentProcessSampleLog;
import com.zhijian.medical.entity.vo.request.ExperimentProcessSampleSearchVo;
import com.zhijian.medical.entity.vo.response.ExperimentProcessSampleVo;
import com.zhijian.medical.enums.AllExperimentationStepStatusEnum;
import com.zhijian.medical.enums.ExperimentFishStatusEnum;
import com.zhijian.medical.enums.ExperimentTypeEnum;
import com.zhijian.medical.enums.ResponseCodeEnum;
import com.zhijian.medical.exception.BusinessException;
import com.zhijian.medical.holder.CurrentUserHolder;
import com.zhijian.medical.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author li xiao dong
 * @since 2022-08-12
 */
@Service
public class FishHybridServiceImpl extends ServiceImpl<FishHybridMapper, ExperimentFishHybrid> implements FishHybridService {

    @Autowired
    private FishHybridMapper hybridMapper;
    @Autowired
    private FishHybridOplogService hybridOplogService;

    @Autowired
    private FishService fishService;

    @Autowired
    private ExperimentProcessSampleService sampleService;

    @Autowired
    private ExperimentProcessSampleLogService sampleLogService;

    @Transactional(rollbackFor = Exception.class, value = "localTransactionManager")
    @Override
    public Boolean create(ExperimentFishHybrid experimentFishHybrid) {
        deleteHybridByFishId(experimentFishHybrid.getFishId());
        Long hybridId = insert(experimentFishHybrid);
        for (ExperimentFishHybridOplog hybridOplog : experimentFishHybrid.getZjRecord()) {
            hybridOplog.setHybridId(hybridId);
            hybridOplogService.insert(hybridOplog);
        }

        //修改FISH实验的总状态
        fishService.updateByPrimaryKeySelective(ExperimentFish.builder().id(experimentFishHybrid.getFishId()).status(ExperimentFishStatusEnum.ZJS.getCode().byteValue()).build());

        List<ExperimentProcessSampleVo> sampleVoList = sampleService.selectList(ExperimentProcessSampleSearchVo.builder()
                .mainType(ExperimentTypeEnum.FISH.getCode().byteValue())
                .experimentProcessId(experimentFishHybrid.getFishId())
                .build());
        ExperimentFish fish = fishService.detail(experimentFishHybrid.getFishId());
        sampleLogService.saveBatch(sampleVoList.stream().map(e -> ExperimentProcessSampleLog.builder()
                .sampleId(e.getId())
                .fishId(experimentFishHybrid.getFishId())
                .mainType(ExperimentTypeEnum.FISH.getCode().byteValue())
                .op(String.format("%s%s-%s", fish.getName(), fish.getExperimentNum(), ExperimentFishStatusEnum.ZJS.getDesc()))
                .opUser(CurrentUserHolder.getUser().getName())
                .build()).collect(Collectors.toList()));
        return true;
    }

    @Override
    public Long insert(ExperimentFishHybrid experimentFishHybrid) {
        int count = hybridMapper.insert(experimentFishHybrid);
        if (count <= 0) {
            throw new BusinessException(ResponseCodeEnum.FAILURE.code, "杂交室创建失败");
        }
        return experimentFishHybrid.getId();
    }

    public Boolean deleteHybridByFishId(Long fishId) {
        delete(fishId);
        hybridOplogService.deleteByFishId(fishId);
        return true;
    }

    public Boolean delete(Long fishId) {
        QueryWrapper<ExperimentFishHybrid> experimentFishHybridQueryWrapper = new QueryWrapper<>();
        experimentFishHybridQueryWrapper.eq("fish_id", fishId);
        return hybridMapper.delete(experimentFishHybridQueryWrapper) > 0;
    }

    @Override
    public ExperimentFishHybrid detail(Long fishId) {
        ExperimentFishHybrid hybrid = selectOne(fishId);
        if (hybrid == null) {
            hybrid = new ExperimentFishHybrid();
        }
        hybrid.setZjRecord(hybridOplogService.list(fishId));
        ExperimentFish experimentFish = fishService.selectByPrimaryKey(fishId);
        hybrid.setResult(experimentFish.getStatus() >= ExperimentFishStatusEnum.ZJS.getCode().byteValue() ?
                AllExperimentationStepStatusEnum.END.getCode().byteValue() : AllExperimentationStepStatusEnum.UN_END.getCode().byteValue());
        hybrid.setResultStr(experimentFish.getStatus() >= ExperimentFishStatusEnum.ZJS.getCode().byteValue() ?
                AllExperimentationStepStatusEnum.END.getDesc() : AllExperimentationStepStatusEnum.UN_END.getDesc());

        return hybrid;
    }

    public ExperimentFishHybrid selectOne(Long fishId) {
        QueryWrapper<ExperimentFishHybrid> experimentFishHybridQueryWrapper = new QueryWrapper<>();
        experimentFishHybridQueryWrapper.eq("fish_id", fishId);
        return hybridMapper.selectOne(experimentFishHybridQueryWrapper);
    }
}
